package com.coincalf.wallet.blockchain.util;

import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Base64;

public class HttpUtil {

    private static final Logger log = LoggerFactory.getLogger(HttpUtil.class);

    /**
     * 连接请求超时时间 单位：毫秒
     */
    private static final int connectTimeout = 4000;

    /**
     * 连接传输超时时间 单位：毫秒
     */
    private static final int transferTimeout = 10000;

    /**
     * 绕过验证
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
        SSLContext sc = SSLContext.getInstance("SSLv3");
        // 实现一个X509TrustManager接口，用于绕过验证，不用修改里面的方法
        X509TrustManager trustManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(
                java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                String paramString) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(
                java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                String paramString) throws CertificateException {
            }

            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        sc.init(null, new TrustManager[]{trustManager}, null);
        return sc;
    }

    public static String doPost(String url, String jsonStr) {
        return doPost(url, jsonStr, "", "");
    }

    public static String doPost(String url, String jsonStr, String userName, String password) {
        String result = null;
        try {
            //采用绕过验证的方式处理https请求
            SSLContext sslcontext = createIgnoreVerifySSL();

            // 设置协议http和https对应的处理socket链接工厂的对象
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .register("https", new SSLConnectionSocketFactory(sslcontext))
                .build();
            PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            HttpClients.custom().setConnectionManager(connManager);

            //创建自定义的httpclient对象
            CloseableHttpClient closeableHttpClient = HttpClients.custom().setConnectionManager(connManager).build();
            //创建post方式请求对象
            HttpPost httpPost = new HttpPost(url);
            //设置请求超时和传输超时
            RequestConfig build = RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(transferTimeout).build();
            httpPost.setConfig(build);
            httpPost.addHeader("Content-Type", "application/json");

            //  basic auth认证
            httpPost.addHeader("Authorization", "Basic " + Base64.getUrlEncoder().encodeToString((userName + ":" + password).getBytes()));

            StringEntity se = new StringEntity(jsonStr);
            se.setContentType("text/json");
            se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
            httpPost.setEntity(se);
            CloseableHttpResponse response = closeableHttpClient.execute(httpPost);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, "utf-8");
                }
            }
            // 关闭连接
            closeableHttpClient.close();
        } catch (NoSuchAlgorithmException | KeyManagementException | IOException | ParseException e) {
            log.error("接口调用失败 url={}, e={}", url, e);
            return null;
        }
        return result;
    }

    public static String doGet(String url) {
        return doGet(url, "", "");
    }

    public static String doGet(String url, String userName, String password) {
        String result = null;
        try {
            //采用绕过验证的方式处理https请求
            SSLContext sslcontext = createIgnoreVerifySSL();
            //            SSLContext sslcontext = SSLContext.getInstance("TLSv1.2");
            //            sslcontext.init(null,null,null);
            //            			SSLContext.setDefault(sslcontext);
            // 设置协议http和https对应的处理socket链接工厂的对象
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .register("https", new SSLConnectionSocketFactory(sslcontext))
                .build();
            PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            HttpClients.custom().setConnectionManager(connManager);

            //创建自定义的httpclient对象
            CloseableHttpClient closeableHttpClient = HttpClients.custom().setConnectionManager(connManager).build();
            //	CloseableHttpClient client = HttpClients.createDefault();

            //创建post方式请求对象
            HttpGet httpGet = new HttpGet(url);
            RequestConfig timeoutCfg = RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(transferTimeout).build();
            httpGet.setConfig(timeoutCfg);
            httpGet.setHeader("Content-Type", "application/json");

            //  basic auth认证
            httpGet.addHeader("Authorization", "Basic " + Base64.getUrlEncoder().encodeToString((userName + ":" + password).getBytes()));

            CloseableHttpResponse response = closeableHttpClient.execute(httpGet);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, "utf-8");
                }
            }
            // 关闭连接
            closeableHttpClient.close();
        } catch (NoSuchAlgorithmException | KeyManagementException | IOException | ParseException e) {
            log.error("接口调用失败 url={}, e={}", url, e);
            return null;
        }
        return result;
    }

    public static String doPut(String url, String jsonStr, String userName, String password) {
        String result = null;
        try {
            //采用绕过验证的方式处理https请求
            SSLContext sslcontext = createIgnoreVerifySSL();

            // 设置协议http和https对应的处理socket链接工厂的对象
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .register("https", new SSLConnectionSocketFactory(sslcontext))
                .build();
            PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            HttpClients.custom().setConnectionManager(connManager);

            //创建自定义的httpclient对象
            CloseableHttpClient closeableHttpClient = HttpClients.custom().setConnectionManager(connManager).build();

            //创建post方式请求对象
            HttpPut httpPut = new HttpPut(url);
            RequestConfig timeoutCfg = RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(transferTimeout).build();
            httpPut.setConfig(timeoutCfg);
            httpPut.setHeader("Content-Type", "application/json");

            StringEntity se = new StringEntity(jsonStr);
            se.setContentType("text/json");
            se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
            httpPut.setEntity(se);
            //  basic auth认证
            httpPut.addHeader("Authorization", "Basic " + Base64.getUrlEncoder().encodeToString((userName + ":" + password).getBytes()));

            CloseableHttpResponse response = closeableHttpClient.execute(httpPut);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, "utf-8");
                }
            }
            // 关闭连接
            closeableHttpClient.close();
        } catch (NoSuchAlgorithmException | KeyManagementException | IOException | ParseException e) {
            log.error("接口调用失败 url={}, e={}", url, e);
            return null;
        }
        return result;
    }

    public static String doDelete(String url, String jsonStr, String userName, String password) {
        String result = null;
        try {
            //采用绕过验证的方式处理https请求
            SSLContext sslcontext = createIgnoreVerifySSL();

            // 设置协议http和https对应的处理socket链接工厂的对象
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .register("https", new SSLConnectionSocketFactory(sslcontext))
                .build();
            PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            HttpClients.custom().setConnectionManager(connManager);

            //创建自定义的httpclient对象
            CloseableHttpClient closeableHttpClient = HttpClients.custom().setConnectionManager(connManager).build();

            //创建post方式请求对象
            HttpDelete httpDelete = new HttpDelete(url);

            RequestConfig timeoutCfg = RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(transferTimeout).build();
            httpDelete.setConfig(timeoutCfg);
            httpDelete.setHeader("Content-Type", "application/json");

            //  basic auth认证
            httpDelete.addHeader("Authorization", "Basic " + Base64.getUrlEncoder().encodeToString((userName + ":" + password).getBytes()));

            CloseableHttpResponse response = closeableHttpClient.execute(httpDelete);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, "utf-8");
                }
            }
            // 关闭连接
            closeableHttpClient.close();
        } catch (NoSuchAlgorithmException | KeyManagementException | IOException | ParseException e) {
            log.error("接口调用失败 url={}, e={}", url, e);
            return null;
        }
        return result;
    }

}
